from classes.Leilao import Leilao
from classes.ParametrosUsuario import ParametrosUsuario
from random import randint
import unittest


class TesteLeilao(unittest.TestCase):
    def setUp(self):
        self.parametrosParaPerfeitamenteRacionais = ParametrosUsuario()
        self.parametrosParaPerfeitamenteRacionais.distribuicaoDinheiroDisponivel = "normal"
        self.parametrosParaPerfeitamenteRacionais.distribuicaoValorParaParticipante = "normal"
        self.parametrosParaPerfeitamenteRacionais.numeroDeLeiloes = 1
        self.parametrosParaPerfeitamenteRacionais.numeroDeParticipantes = 10
        self.parametrosParaPerfeitamenteRacionais.parametrosDinheiroDisponivel = [400, 200]
        self.parametrosParaPerfeitamenteRacionais.parametrosValorParaParticipante = [400, 100]
        self.parametrosParaPerfeitamenteRacionais.perfeitamenteRacionais = True
        self.parametrosParaPerfeitamenteRacionais.valorRealDoProduto = 500
        self.parametrosParaPerfeitamenteRacionais.valorInicial = 50
        self.parametrosParaPerfeitamenteRacionais.aumentoMinimo = 25

        self.parametrosParaPerfisDiferentes = ParametrosUsuario()
        self.parametrosParaPerfisDiferentes.distribuicaoDinheiroDisponivel = "normal"
        self.parametrosParaPerfisDiferentes.distribuicaoValorParaParticipante = "normal"
        self.parametrosParaPerfisDiferentes.numeroDeLeiloes = 1
        self.parametrosParaPerfisDiferentes.numeroDeParticipantes = 10
        self.parametrosParaPerfisDiferentes.parametrosDinheiroDisponivel = [400, 200]
        self.parametrosParaPerfisDiferentes.parametrosValorParaParticipante = [400, 100]
        self.parametrosParaPerfisDiferentes.perfeitamenteRacionais = False
        self.parametrosParaPerfisDiferentes.valorRealDoProduto = 500
        self.parametrosParaPerfisDiferentes.valorInicial = 50
        self.parametrosParaPerfisDiferentes.aumentoMinimo = 25
        self.parametrosParaPerfisDiferentes.quantidadeDeParticipantesAgressivos = 3
        self.parametrosParaPerfisDiferentes.quantidadeDeParticipantesCautelosos = 2
        self.parametrosParaPerfisDiferentes.quantidadeDeParticipantesModerados = 5

        self.leilaoPerfeitamenteRacional = Leilao(self.parametrosParaPerfeitamenteRacionais)

    def testeEscolheProximoParticipante(self):
        i = self.leilaoPerfeitamenteRacional.escolheProximoParticipante()

        self.assertGreaterEqual(i, 0)
        self.assertLessEqual(i, self.leilaoPerfeitamenteRacional.numeroDeParticipantes)

    def testeSomaTempos(self):
        soma = self.leilaoPerfeitamenteRacional.somaTempos()

        self.assertGreaterEqual(soma, self.leilaoPerfeitamenteRacional.numeroDeParticipantes)
        self.assertLessEqual(soma, 10 * self.leilaoPerfeitamenteRacional.numeroDeParticipantes)

    def testeParticipanteDesiste(self):
        soma = self.leilaoPerfeitamenteRacional.somaTempos()
        indice = randint(0, self.leilaoPerfeitamenteRacional.numeroDeParticipantes - 1)

        self.leilaoPerfeitamenteRacional.participanteDesiste(indice)

        somaFinal = self.leilaoPerfeitamenteRacional.somaDosTemposDeResposta

        self.assertEqual(self.leilaoPerfeitamenteRacional.participando.count(True), self.leilaoPerfeitamenteRacional.numeroDeParticipantes - 1)
        self.assertEqual(somaFinal, soma - self.leilaoPerfeitamenteRacional.participantes[indice].tempoDeResposta)

    def testeAtualizaValor(self):
        valor = 100
        vencedor = 1

        self.leilaoPerfeitamenteRacional.atualizaValor(valor, vencedor)

        self.assertEqual(self.leilaoPerfeitamenteRacional.valorAtual, valor)
        self.assertEqual(self.leilaoPerfeitamenteRacional.vencedorAtual, vencedor)

        i = len(self.leilaoPerfeitamenteRacional.historicoDosLances) - 1
        j = len(self.leilaoPerfeitamenteRacional.autorDoLance) - 1

        self.assertEqual(self.leilaoPerfeitamenteRacional.historicoDosLances[i], valor)
        self.assertEqual(self.leilaoPerfeitamenteRacional.autorDoLance[j], vencedor)

    def testaSeOsLancesSaoCrescentesParaParticipantesPerfeitamenteRacionais(self):
        leilao = Leilao(self.parametrosParaPerfeitamenteRacionais)

        lances = leilao.iniciaLeilao()
        lances = lances[0]

        for i in range(1, len(lances)):
            self.assertLess(lances[i - 1], lances[i])

    def testaSeOsLancesSaoDadosPorParticipantesDiferentesParaParticipantesPerfeitamenteRacionais(self):
        leilao = Leilao(self.parametrosParaPerfeitamenteRacionais)

        vencedores = leilao.iniciaLeilao()
        vencedores = vencedores[1]

        for i in range(1, len(vencedores)):
            self.assertNotEqual(vencedores[i - 1], vencedores[i])

    def testaSeOsLancesSaoCrescentesParaParticipantesComPerfisDiferentes(self):
        leilao = Leilao(self.parametrosParaPerfisDiferentes)

        lances = leilao.iniciaLeilao()
        lances = lances[0]

        for i in range(1, len(lances)):
            self.assertLess(lances[i - 1], lances[i])

    def testaSeOsLancesSaoDadosPorParticipantesDiferentesParaParticipantesComPerfisDiferentes(self):
        leilao = Leilao(self.parametrosParaPerfisDiferentes)

        vencedores = leilao.iniciaLeilao()
        vencedores = vencedores[1]

        for i in range(1, len(vencedores)):
            self.assertNotEqual(vencedores[i - 1], vencedores[i])

    def testaSeOVencedorAtualNaoESorteadoParaDarOLance(self):
        leilao = Leilao(self.parametrosParaPerfeitamenteRacionais)

        leilao.vencedorAtual = 0

        i = 0
        while i < 100:
            num = leilao.escolheProximoParticipante()
            self.assertNotEqual(leilao.vencedorAtual, num)
            i += 1

    def testaSeTodosOsParticipantesSaoSorteados(self):
        leilao = Leilao(self.parametrosParaPerfeitamenteRacionais)

        sorteados = leilao.numeroDeParticipantes * [False]

        for i in range(leilao.numeroDeParticipantes * 100):
            num = leilao.escolheProximoParticipante()
            sorteados[num] = True

        for i in range(leilao.numeroDeParticipantes):
            self.assertTrue(sorteados[i], "Nao sorteado: " + str(i))

    def testaSeASomaDosTemposDeRespostaNuncaFicaNegativa(self):
        leilao = Leilao(self.parametrosParaPerfeitamenteRacionais)

        for i in range(leilao.numeroDeParticipantes):
            leilao.participanteDesiste(i)
            self.assertGreaterEqual(leilao.somaDosTemposDeResposta, 0)

    def testaSeNaoSorteiaParaOfertaUmParticipanteQueJaDesistiu(self):
        leilao = Leilao(self.parametrosParaPerfeitamenteRacionais)

        leilao.participanteDesiste(5)

        i = 0
        while i < 100:
            num = leilao.escolheProximoParticipante()
            self.assertNotEqual(num, 5)
            i += 1
